package interfaces.subpanel.classifier;

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.event.MouseEvent;

import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.table.AbstractTableModel;
import javax.swing.table.JTableHeader;
import javax.swing.table.TableColumnModel;
import javax.swing.text.Style;

import utils.ImagenesUtils;

public class ConfusionMatrix extends JPanel {

	private static final int COLUMNS_COUNT = 19;

	private static final long serialVersionUID = 1L;

	private static final int ATTRIBUTE_COLUMN_WIDTH = 27;

	private JTable table;

	private TableModel model = new TableModel();

	protected String[] columnToolTips = { "FUNCTIONALITY", "PERFORMANCE", "SECURITY", "AVAILABILITY", "USABILITY", "INTEROPERABILITY", "RELIABILITY",
			"LOOK AND FEEL", "MODIFIABILITY", "PORTABILITY", "REUSABILITY", "INTEGRABILITY", "TESTABILITY", "MAINTAINABILITY", "OPERATIONAL",
			"SCALABILITY", "FAULT TOLERANCE", "LEGAL" };

	public ConfusionMatrix() {

		super();
		this.table = new JTable(this.model) {
			private static final long serialVersionUID = 1L;

			// Implement table header tool tips.
			protected JTableHeader createDefaultTableHeader() {
				return new JTableHeader(columnModel) {
					private static final long serialVersionUID = 1L;

					public String getToolTipText(MouseEvent e) {
						java.awt.Point p = e.getPoint();
						int index = columnModel.getColumnIndexAtX(p.x);
						int realIndex = columnModel.getColumn(index).getModelIndex() - 1;
						return columnToolTips[realIndex];
					}
				};
			}
		};
		this.table.setEnabled(false);
		this.table.getTableHeader().setPreferredSize(new Dimension(10, 17));
		this.table.getTableHeader().setBackground(Color.LIGHT_GRAY);
		this.table.getTableHeader().setFont(new Font(Font.SANS_SERIF, 0, 10));
		this.table.setFont(new Font(Font.SANS_SERIF, 0, 10));
		this.table.setFillsViewportHeight(true);
		this.table.setPreferredScrollableViewportSize(new Dimension(518, 306));
		this.table.setColumnSelectionAllowed(false);
		this.table.setRowSelectionAllowed(false);
		this.table.setRowHeight(16);
		this.table.setRowHeight(15);
		this.table.setFont(new Font("Verdana", Font.PLAIN, 11));
		for (int colPos = 0; colPos < COLUMNS_COUNT; colPos++)
			this.table.getColumnModel().getColumn(colPos).setMinWidth(ATTRIBUTE_COLUMN_WIDTH);
		// TableColumnModel cmodel = this.table.getColumnModel();
		// cmodel.getColumn(0).setCellRenderer(new LabelCellRenderer());
		JScrollPane scrollPane = new JScrollPane(this.table);
		scrollPane.setBorder(null);
		scrollPane.setBackground(null);
		add(scrollPane);
	}

	public void setValueAt(Object value, int row, int col) {
		this.model.setValueAt(value, row, col);
	}

	public void fillConfusionMatrix(double[][] cmMatrix) {

		try {
			// Starts in 1 to avoid dummy column/row.
			for (int row_i = 1; row_i < cmMatrix.length; row_i++) {
				for (int col_i = 1; col_i < cmMatrix.length; col_i++) {
					this.setValueAt((int) cmMatrix[row_i][col_i], row_i - 1, col_i);
				}
			}
		} catch (Exception e) {
			JOptionPane.showMessageDialog(this, e.getMessage(), "ERROR!", JOptionPane.ERROR_MESSAGE,
					ImagenesUtils.createImageIcon(this.getClass(), "/stop.png"));
		}
	}

	public void clearMatrix() {
		try {
			for (int row_i = 1; row_i < COLUMNS_COUNT; row_i++) {
				for (int col_i = 1; col_i < COLUMNS_COUNT; col_i++) {
					this.setValueAt(0, row_i - 1, col_i);
				}
			}
		} catch (Exception e) {
			JOptionPane.showMessageDialog(this, e.getMessage(), "ERROR!", JOptionPane.ERROR_MESSAGE,
					ImagenesUtils.createImageIcon(this.getClass(), "/stop.png"));
		}
	}

	class TableModel extends AbstractTableModel {

		private static final long serialVersionUID = 1L;

		private String[] columnNames = { "-", "Fu", "Pe", "Se", "Av", "Us", "In", "Re", "Lf", "Mo", "Po", "Ru", "It", "Te", "Ma", "Op", "Sc", "Ft",
				"Le" };

		private Object[][] data = { { "Fu", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0" },
				{ "Pe", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0" },
				{ "Se", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0" },
				{ "Av", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0" },
				{ "Us", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0" },
				{ "In", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0" },
				{ "Re", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0" },
				{ "Lf", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0" },
				{ "Mo", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0" },
				{ "Po", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0" },
				{ "Ru", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0" },
				{ "It", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0" },
				{ "Te", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0" },
				{ "Ma", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0" },
				{ "Op", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0" },
				{ "Sc", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0" },
				{ "Ft", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0" },
				{ "Le", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0" } };

		public int getColumnCount() {
			return this.columnNames.length;
		}

		public int getRowCount() {
			return this.data.length;
		}

		public String getColumnName(int col) {
			return this.columnNames[col];
		}

		public Object getValueAt(int row, int col) {
			if (this.data.length <= row) {
				System.out.println("ERROR: Out of Index while getting data from model in table.");
				return null;
			}
			return data[row][col];
		}

		@SuppressWarnings({ "unchecked", "rawtypes" })
		public Class getColumnClass(int c) {
			return getValueAt(0, c).getClass();
		}

		public boolean isCellEditable(int row, int col) {
			return false;
		}

		public void setValueAt(Object value, int row, int col) {
			if (data.length <= row) {
				System.out.println("ERROR: Out of Index while setting data into data model in table.");
				return;
			}
			data[row][col] = value;
			fireTableCellUpdated(row, col);
		}

	}
}
